import { useEffect, useRef, useState, useCallback } from 'react';
import { io, Socket } from 'socket.io-client';
import { ChatMessage, ChatUser, ChatWebSocketEvents, generateRandomUsername } from '../types/chat';
import { apiClient } from '../lib/api';

interface UseChatOptions {
  autoConnect?: boolean;
  username?: string;
}

interface ChatState {
  connected: boolean;
  connecting: boolean;
  error: string | null;
  messages: ChatMessage[];
  users: ChatUser[];
  currentUser: string | null;
  socket: Socket | null;
}

export function useChat(options: UseChatOptions = {}) {
  const { autoConnect = true, username } = options;
  
  const [state, setState] = useState<ChatState>({
    connected: false,
    connecting: false,
    error: null,
    messages: [],
    users: [],
    currentUser: null,
    socket: null,
  });

  const socketRef = useRef<Socket | null>(null);
  const usernameRef = useRef<string>(username || generateRandomUsername());

  const connect = useCallback(() => {
    if (socketRef.current?.connected) {
      return;
    }

    setState(prev => ({ ...prev, connecting: true, error: null }));

    // 获取基础WebSocket URL（不包含/realtime路径）
    const wsUrl = apiClient.getWebSocketBaseUrl();
    const fullUrl = `${wsUrl}/realtime`;

    console.log('WebSocket connection details:', {
      baseUrl: wsUrl,
      fullUrl: fullUrl,
      hostname: typeof window !== 'undefined' ? window.location.hostname : 'unknown'
    });

    // 连接到 /realtime 命名空间
    const socket = io(fullUrl, {
      path: '/socket.io',
      transports: ['websocket'],
      upgrade: false,
      rememberUpgrade: false,
      forceNew: true,
    });

    socketRef.current = socket;

    socket.on('connect', () => {
      console.log('Chat WebSocket connected');
      console.log('Socket.io details:', {
        id: socket.id,
        connected: socket.connected,
        // @ts-expect-error - 访问私有属性用于调试
        namespace: socket.nsp?.name,
        // @ts-expect-error - 访问私有属性用于调试
        url: socket.io?.uri
      });
      
      setState(prev => ({
        ...prev,
        connected: true,
        connecting: false,
        error: null,
        socket,
      }));

      // 自动加入聊天室
      console.log('Attempting to join chat with username:', usernameRef.current);
      socket.emit('join_chat', { username: usernameRef.current });
    });

    socket.on('disconnect', (reason) => {
      console.log('Chat WebSocket disconnected:', reason);
      setState(prev => ({
        ...prev,
        connected: false,
        connecting: false,
        socket: null,
      }));
    });

    socket.on('connect_error', (error) => {
      console.error('Chat WebSocket connection error:', error);
      setState(prev => ({
        ...prev,
        connected: false,
        connecting: false,
        error: error.message,
        socket: null,
      }));
    });

    // 监听后端发送的连接确认事件
    socket.on('connected', (data) => {
      console.log('Server connection confirmed:', data);
    });

    // 聊天事件处理
    socket.on('user_joined', (data: ChatWebSocketEvents['user_joined']) => {
      console.log('User joined:', data);
      setState(prev => {
        // 避免重复添加用户
        const userExists = prev.users.find(u => u.id === data.user.id);
        if (userExists) return prev;
        
        return {
          ...prev,
          users: [...prev.users, data.user],
          messages: [...prev.messages, {
            id: `system-${Date.now()}`,
            username: 'System',
            message: `${data.user.username} 加入了聊天室`,
            timestamp: data.timestamp,
            isSystem: true,
          }],
        };
      });
      
      // 如果是当前用户，设置currentUser
      if (data.user.username === usernameRef.current) {
        setState(prev => ({ ...prev, currentUser: data.user.username }));
      }
    });

    socket.on('user_left', (data: ChatWebSocketEvents['user_left']) => {
      console.log('User left:', data);
      setState(prev => ({
        ...prev,
        users: prev.users.filter(u => u.id !== data.user.id),
        messages: [...prev.messages, {
          id: `system-${Date.now()}`,
          username: 'System',
          message: `${data.user.username} 离开了聊天室`,
          timestamp: data.timestamp,
          isSystem: true,
        }],
      }));
    });

    socket.on('new_message', (data: ChatWebSocketEvents['new_message']) => {
      console.log('New message:', data);
      setState(prev => ({
        ...prev,
        messages: [...prev.messages, data.message],
      }));
    });

    socket.on('chat_history', (data: ChatWebSocketEvents['chat_history']) => {
      console.log('Chat history:', data);
      setState(prev => ({
        ...prev,
        messages: data.messages,
      }));
    });

    // 监听在线用户列表更新
    socket.on('online_users', (data: ChatWebSocketEvents['online_users']) => {
      console.log('Online users:', data);
      setState(prev => ({
        ...prev,
        users: data.users,
      }));
    });

    // 监听用户名已被使用的错误
    socket.on('username_taken', (data: ChatWebSocketEvents['username_taken']) => {
      console.log('Username taken:', data);
      // 生成新的随机用户名
      usernameRef.current = generateRandomUsername();
      socket.emit('join_chat', { username: usernameRef.current });
    });

  }, []);

  const disconnect = useCallback(() => {
    if (socketRef.current) {
      socketRef.current.emit('leave_chat', {});
      socketRef.current.disconnect();
      socketRef.current = null;
      setState(prev => ({
        ...prev,
        connected: false,
        connecting: false,
        socket: null,
        currentUser: null,
      }));
    }
  }, []);

  const sendMessage = useCallback((message: string) => {
    if (socketRef.current && state.connected && message.trim()) {
      socketRef.current.emit('send_message', { message: message.trim() });
    }
  }, [state.connected]);

  const changeUsername = useCallback((newUsername: string) => {
    if (newUsername.trim() && newUsername !== usernameRef.current) {
      usernameRef.current = newUsername.trim();
      if (socketRef.current && state.connected) {
        // 重新加入聊天室
        socketRef.current.emit('leave_chat', {});
        socketRef.current.emit('join_chat', { username: usernameRef.current });
      }
    }
  }, [state.connected]);

  useEffect(() => {
    if (autoConnect) {
      connect();
    }

    return () => {
      disconnect();
    };
  }, [autoConnect, connect, disconnect]);

  return {
    ...state,
    currentUser: usernameRef.current,
    connect,
    disconnect,
    sendMessage,
    changeUsername,
  };
}
